package org.yaac.shared.property;

import static com.google.common.collect.Lists.newArrayList;

import java.util.Arrays;
import java.util.List;

import org.yaac.shared.egql.ResultCell;
import org.yaac.shared.egql.ResultCell.ResultCellFactory;


import com.google.gwt.safehtml.shared.SafeHtmlUtils;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public class TextPropertyInfo extends PropertyInfo {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static final int DEFAULT_PREVIEW_LEN = 50;
	
	/**
	 * first 100 chars
	 */
	private String preview;
	
	private Integer size;

	private String downloadPath;
	
	/**
	 * user can edit raw text as well
	 */
	private String rawText;
	
	/**
	 * used by GWT
	 */
	@SuppressWarnings("unused")
	private TextPropertyInfo(){}
	
	public TextPropertyInfo(String rawText) {
		super();
		this.rawText = rawText;
	}

	/**
	 * @param preview
	 * @param size
	 * @param downloadPath
	 */
	public TextPropertyInfo(String preview, Integer size, String downloadPath) {
		super();
		this.preview = preview;
		this.size = size;
		this.downloadPath = downloadPath;
	}
	
	public String getPreview() {
		return preview;
	}

	public Integer getSize() {
		return size;
	}

	public String getDownloadPath() {
		return downloadPath;
	}
	
	public String getRawText() {
		return rawText;
	}

	/**
	 * @param fullStr
	 * @param downloadPath
	 */
	public TextPropertyInfo(String fullStr, String downloadPath) {
		super();
		this.downloadPath = downloadPath;
		
		if (fullStr.length() > DEFAULT_PREVIEW_LEN) {
			this.preview = fullStr.substring(0, DEFAULT_PREVIEW_LEN);
			this.size = fullStr.length();	
		} else {
			this.preview = fullStr;
			this.size = -1;	// meaningless
		}
	}
	
	@Override
	public int compareTo(PropertyInfo o) {
		if (o instanceof TextPropertyInfo) {
			return this.preview.compareTo(((TextPropertyInfo) o).preview);
		} else {
			return 0;	
		}
	}

	@Override
	public String asHtml() {
		// TODO i18n
		if (rawText != null) {
			return rawText;
		} else if (size == -1) {
			return preview;	// very short Text
		} else {
			return preview + "<a href='/download?path=" + SafeHtmlUtils.htmlEscape(downloadPath) + "' target='blank'>[Total size = " + size + " bytes]</a>";
		}
	}

	@Override
	public ResultCell populateResultCell(ResultCellFactory factory) {
		ResultCell cell = super.populateResultCell(factory);
		cell.setType(PropertyType.TEXT);
		cell.setParent(null);
		cell.setChildren(null);
		cell.setPayload(Arrays.asList(preview, size.toString(), downloadPath));
		return cell;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((downloadPath == null) ? 0 : downloadPath.hashCode());
		result = prime * result + ((preview == null) ? 0 : preview.hashCode());
		result = prime * result + ((rawText == null) ? 0 : rawText.hashCode());
		result = prime * result + ((size == null) ? 0 : size.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		TextPropertyInfo other = (TextPropertyInfo) obj;
		if (downloadPath == null) {
			if (other.downloadPath != null)
				return false;
		} else if (!downloadPath.equals(other.downloadPath))
			return false;
		if (preview == null) {
			if (other.preview != null)
				return false;
		} else if (!preview.equals(other.preview))
			return false;
		if (rawText == null) {
			if (other.rawText != null)
				return false;
		} else if (!rawText.equals(other.rawText))
			return false;
		if (size == null) {
			if (other.size != null)
				return false;
		} else if (!size.equals(other.size))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "TextPropertyInfo [preview=" + preview + ", size=" + size + ", downloadPath=" + downloadPath
				+ ", rawText=" + rawText + "]";
	}

	@Override
	public String asExpression(FilePlaceHolder placeHolder) {
		if (rawText == null) {
			return "text(" + placeHolder.next() + ")";
		} else {
			return "text('" + rawText + "')";
		}
	}

	@Override
	public List<String> downloadPaths() {
		if (this.rawText == null) {
			return newArrayList(this.downloadPath);
		} else {
			return newArrayList();
		}
	}
}
